﻿//-----------------------------------------------------------------------------------------------------------
//  Description:
//      职位相关
//      
//      
//  Comment                          Date                 Author      Email
//   ----------------------------    -------             -------      -----------------------------------
//  Create                           2012/10/22           wukun       17622690@qq.com
//
// 
//-----------------------------------------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Forest.Cat.Domain.Services;
using Forest.Cat.Domain.Services.Catalog;
using Forest.Core.Data;
using Forest.Cat.Domain.Entities;
using Forest.Cat.Web.Models;
using Forest.Cat.Domain.Services.WantAds;
using Forest.Cat.Web.Extensions;
using Forest.Cat.Domain.Shared;
using Forest.Cat.Web.Models.Catalog;
using Forest.Cat.Domain.Configuration;
using Forest.Cat.Domain.Services.Compnaies;
using Forest.Cat.Domain;
using Forest.Cat.Domain.Services.Pictures;
using Forest.Cat.Domain.Services.Applications;
using Forest.Cat.Domain.Services.JobHunting;
using Forest.Core;
using System.Text;
using Forest.Cat.Domain.Services.HomePages;
using System.Web.Routing;

namespace Forest.Cat.Web.Controllers
{
    public class CatalogController : BaseController
    {
        #region Const
        private const int _pageSize = 15;
        #endregion

        #region Fields
        private readonly IJobPositionService _jobPositionService;
        private readonly IApplicationService _applicationService;
        private readonly ILovService _lovService;
        private readonly ICompanyService _companyService;
        private readonly INewsService _newsService;
        private readonly IWorkContext _workContext;
        private readonly IPictureService _pictureService;
        private readonly ISavedJobService _savedJobService;
        private readonly IHomePageService _homePageService;

        #endregion

        #region Constructures
        public CatalogController(IWorkContext workContext,
            IJobPositionService jobPositionService,
            IApplicationService applicationService,
            ILovService lovService,
            INewsService newsService,
            ICompanyService companyService,
            IPictureService pictureService,
            ISavedJobService savedJobService,
            IHomePageService homePageService)
        {
            _workContext = workContext;
            _jobPositionService = jobPositionService;
            _applicationService = applicationService;
            _lovService = lovService;
            _newsService = newsService;
            _companyService = companyService;
            _pictureService = pictureService;
            _savedJobService = savedJobService;
            _homePageService = homePageService;
        }
        #endregion

        #region Methods

        #region JobView
        public ActionResult JobView(Guid id)
        {
            var job = _jobPositionService.GetJobPositionById(id);
            if (job != null && job.Deleted == false && job.Status == (int)Status.Publish)
            {
                job.Views = (job.Views ?? 0) + 1;
                _jobPositionService.UpdateJobPosition(job);
                //将访问的职位ID记录到Cookie中
                AddJobIdToCookie(id);
                //已申请过的职位列表
                IQueryable<Guid> appliedJobIdList = null;
                if (_workContext.CurrentUser != null)
                {
                    appliedJobIdList = _applicationService.GetApplicationsByJobseekerId(_workContext.CurrentUser.Id).Select(x => x.JobPositionId);
                }
                try
                {
                    var model = PrepareJobModel(job, null);
                    //获取Logo
                    var logoInfoId = _pictureService.GetCompanyPicturesId(model.CompanyModel.Id, true).Select(x => (Guid?)x).FirstOrDefault();
                    model.CompanyModel.CompanyLogoId = logoInfoId;
                    //是否已申请过该职位
                    if (appliedJobIdList != null)
                    {
                        model.IsApplied = appliedJobIdList.Any(x => x.Equals(id));
                    }
                    return View(model);
                }
                catch (NoDataFoundException)
                {
                    return RedirectToAction("NoInfo", "Home");
                }
            }
            else
            {
                return RedirectToAction("NoInfo", "Home");
            }
        }

        /// <summary>
        /// 将访问的职位ID记录到Cookie中
        /// </summary>
        /// <param name="id"></param>
        private void AddJobIdToCookie(Guid id)
        {
            if (Request.Cookies["ViewdJobs"] == null)
            {
                Response.Cookies.Add(new HttpCookie("ViewdJobs", String.Empty) { Expires = DateTime.Now.AddMonths(1) });
            }
            var viewdJobs = Request.Cookies["ViewdJobs"].Value.Split(',').ToList();
            //如果未在Cookie中检索到当前职位信息
            if (!viewdJobs.Any(x => x.Equals(id.ToString())))
            {
                viewdJobs.Insert(0, id.ToString());
                //只保留前十个职位Id
                if (viewdJobs.Count > 10)
                {
                    viewdJobs.RemoveRange(10, viewdJobs.Count - 10);
                }
                Response.Cookies["ViewdJobs"].Value = viewdJobs.Aggregate(String.Empty, (jobsId, next) => next + "," + jobsId);
            }
        }
        #endregion

        #region Browse
        //
        // GET: /Job/
        public ActionResult Browse()
        {
            return View();
        }
        #endregion

        #region SearchJobList
        public ActionResult SearchJobList(PagingFilteringModel command,
            String jobTitle = "",
            String companyName = "",
            String lovCondition = "",
            bool isAdvSearch = false,
            JobListOrderMode orderMode = JobListOrderMode.Reposted)
        {
            if (command.PageSize <= 0) command.PageSize = _pageSize;
            if (command.PageNumber <= 0) command.PageNumber = 1;
            IPagedList<JobPosition> jobList = null;
            var searchCount = 0;
            IQueryable<JobPosition> queryJobList = null;
            //判断是否高级检索
            if (isAdvSearch && Session["AdvSearchConditionModel"] != null)
            {
                AdvSearchConditionModel conditionModel = Session["AdvSearchConditionModel"] as AdvSearchConditionModel;
                queryJobList = _jobPositionService.AdvSearchJobList(conditionModel.KeyWord, conditionModel.Industry1, conditionModel.Industry2,
                    conditionModel.JobCategory1, conditionModel.JobCategory2, conditionModel.EducationLevelList,
                    conditionModel.JobTypeList, conditionModel.CompanyType, conditionModel.PostedDate, orderMode, lovCondition);
                ViewBag.KeyWord = conditionModel.KeyWord;
            }
            else
            {
                Session["AdvSearchConditionModel"] = null;
                queryJobList = _jobPositionService.FindJobList(jobTitle, companyName, orderMode, lovCondition);
                ViewBag.KeyWord = !String.IsNullOrWhiteSpace(jobTitle) ? jobTitle : companyName;
            }
            //检索到的记录总数
            searchCount = queryJobList.Count();
            //获取当前页的数据
            jobList = _jobPositionService.GetJobPagedList(command.PageNumber - 1, _pageSize, queryJobList);
            //已申请过的职位列表
            var appliedJobPostingIdList = new List<Guid>();
            if (_workContext.CurrentUser != null)
            {
                appliedJobPostingIdList = _applicationService.GetApplicationsByJobseekerId(
                    _workContext.CurrentUser.Id).Select(x => x.JobPositionId).ToList();
            }
            var model = new JobListModel()
            {
                JobList = jobList.Select(x => PrepareJobModel(x, appliedJobPostingIdList)).ToList(),
                JobTitle = jobTitle,
                CompanyName = companyName,
                //LovValue = lovValue.HasValue ? lovValue.Value.ToString() : String.Empty,
                SearchCount = searchCount,
                PagingFilteringContext = new PagingFilteringModel(),
                IsAdvSearch = isAdvSearch,
                OrderMode = orderMode
            };
            model.PagingFilteringContext.LoadPagedList(jobList);

            var startDateConditionList = new List<SelectListItem>()
            {
                new SelectListItem(){ Text = "一天内", Value = JobListOrderMode.OneDay.ToString(), Selected=orderMode == JobListOrderMode.OneDay},
                new SelectListItem(){ Text = "三天内", Value = JobListOrderMode.ThreeDay.ToString(), Selected=orderMode == JobListOrderMode.ThreeDay},
                new SelectListItem(){ Text = "一周内", Value = JobListOrderMode.OneWeek.ToString(), Selected=orderMode == JobListOrderMode.OneWeek},
                new SelectListItem(){ Text = "两周内", Value = JobListOrderMode.TwoWeek.ToString(), Selected=orderMode == JobListOrderMode.TwoWeek},
            };
            //如果是按照更新日排序，则为发布日期下拉框加入首选项
            if (orderMode == JobListOrderMode.Reposted)
            {
                startDateConditionList.Insert(0, new SelectListItem() { Text = "按发布日", Value = String.Empty, Selected = true });
            }
            model.StartDateConditionList = startDateConditionList;
            //获取当前检索的职位分类条件，将其在页面上显示(高级检索的职位分类因为可以有多个，所以直接无视)
            if (!isAdvSearch)
            {
                ViewBag.JobCategory = String.Empty;
                var lovConditionList = lovCondition.Split('|').Where(x => !String.IsNullOrWhiteSpace(x)).ToList();
                lovConditionList.ForEach(x =>
                {
                    var lovType = (LovType)Enum.Parse(typeof(LovType), x.Split('-')[0]);
                    var lovValue = int.Parse(x.Split('-')[1]);
                    //如果遍历到职位分类条件
                    if (lovType == LovType.JobCategory)
                    {
                        //将职位分类条件记录下来
                        ViewBag.JobCategory = _lovService.GetLovName(lovValue);
                    }
                });
            }

            ViewBag.LovCondition = lovCondition;
            ViewBag.IsAdvSearch = false;
            ViewBag.CompanyName = companyName;
            ViewBag.JobTitle = jobTitle;

            return View(model);
        }


        public PartialViewResult JobCategoryInfo(String jobTitle = "", String companyName = "", String lovCondition = "", JobListOrderMode orderMode = JobListOrderMode.Reposted)
        {
            ViewBag.IsAdvSearch = false;
            ViewBag.CompanyName = companyName;
            ViewBag.JobTitle = jobTitle;
            var jobLovModelList = new List<JobLovModel>();
            //取出Category信息
            IList<LovInfoForSearchListView> categoryList = null;
            //如果是高级检索
            if (Session["AdvSearchConditionModel"] != null)
            {
                ViewBag.IsAdvSearch = true;
                AdvSearchConditionModel conditionModel = Session["AdvSearchConditionModel"] as AdvSearchConditionModel;
                categoryList = _jobPositionService.GetLovInfoList(conditionModel.KeyWord, conditionModel.Industry1, conditionModel.Industry2,
                    conditionModel.JobCategory1, conditionModel.JobCategory2, conditionModel.EducationLevelList,
                    conditionModel.JobTypeList, conditionModel.CompanyType, conditionModel.PostedDate, LovType.JobCategory, orderMode, lovCondition);
            }
            else
            {
                categoryList = _jobPositionService.GetLovInfoList(jobTitle, companyName, LovType.JobCategory, orderMode, lovCondition);
            }
            var rootIdList = categoryList.Select(i => i.ParentId).Distinct();
            rootIdList.ToList().ForEach(rootId =>
            {
                var rootLov = _lovService.GetAll().FirstOrDefault(i => i.Id.Equals(rootId));
                if (rootLov != null)
                {
                    var jobLovModel = new JobLovModel()
                    {
                        Name = rootLov.Name,
                        Value = rootLov.Value.Value,
                        SubList = new List<JobLovModel>()
                    };
                    jobLovModel.SubList.AddRange(categoryList.Where(i => i.ParentId.Value.Equals(rootId)).Select(i => new JobLovModel()
                    {
                        Name = i.Name,
                        Total = i.Total,
                        Value = i.Value,
                        LovType = LovType.JobCategory
                    }));
                    jobLovModelList.Add(jobLovModel);
                }
            });
            return PartialView(jobLovModelList);
        }

        public PartialViewResult JobLovInfo(LovType lovType, String jobTitle = "", String companyName = "", String lovCondition = "", JobListOrderMode orderMode = JobListOrderMode.Reposted)
        {
            ViewBag.IsAdvSearch = false;
            ViewBag.CompanyName = companyName;
            ViewBag.JobTitle = jobTitle;
            JobLovModel jobLovModel = null;
            IList<LovInfoForSearchListView> lovList = null;
            //如果是高级检索
            if (Session["AdvSearchConditionModel"] != null)
            {
                ViewBag.IsAdvSearch = true;
                AdvSearchConditionModel conditionModel = Session["AdvSearchConditionModel"] as AdvSearchConditionModel;
                lovList = _jobPositionService.GetLovInfoList(conditionModel.KeyWord, conditionModel.Industry1, conditionModel.Industry2,
                    conditionModel.JobCategory1, conditionModel.JobCategory2, conditionModel.EducationLevelList,
                    conditionModel.JobTypeList, conditionModel.CompanyType, conditionModel.PostedDate, lovType, orderMode, lovCondition);
            }
            else
            {
                lovList = _jobPositionService.GetLovInfoList(jobTitle, companyName, lovType, orderMode, lovCondition);
            }
            if (lovList.Any())
            {
                var rootLov = _lovService.GetAll().FirstOrDefault(i => !String.IsNullOrWhiteSpace(i.Label) && i.Label.Equals(lovType.ToString()));
                if (rootLov != null)
                {
                    jobLovModel = new JobLovModel()
                    {
                        Name = rootLov.Name,
                        SubList = new List<JobLovModel>()
                    };
                    jobLovModel.SubList.AddRange(lovList.Select(i => new JobLovModel()
                    {
                        Name = i.Name,
                        Total = i.Total,
                        Value = i.Value,
                        LovType = lovType
                    }));
                }
            }
            return PartialView(jobLovModel);
        }

        #endregion

        #region JobLovBrowse
        public ActionResult JobLovBrowse(LovType lovType = LovType.JobCategory)
        {
            var jobLovModelList = new List<JobLovModel>();
            var lovList = _lovService.GetLovList(lovType).ToList();
            var rootLabelist = lovList.Select(i => i.Label).Distinct();
            rootLabelist.ToList().ForEach(rootLabel =>
            {
                //根节点
                var rootLov = new JobLovModel()
                {
                    Name = rootLabel,
                    SubList = new List<JobLovModel>()
                };
                //第一层节点
                var firstLovList = lovList.Where(i => i.Label.Equals(rootLabel)).Select(x => new JobLovModel()
                {
                    Id = x.Id,
                    Name = x.Name,
                    SubList = new List<JobLovModel>(),
                    Value = x.Value.Value
                }).ToList();
                //第二层节点
                firstLovList.ToList().ForEach(x =>
                {
                    var secondLovList = _lovService.GetLovByParentId(x.Id).ToList().Select(y => new JobLovModel()
                    {
                        Name = y.Name,
                        LovType = lovType,
                        Value = y.Value.Value,
                        Id = y.Id
                    });
                    x.SubList.AddRange(secondLovList);
                });
                rootLov.SubList.AddRange(firstLovList);
                jobLovModelList.Add(rootLov);
            });
            var jobBrowseModel = new JobBrowseModel()
            {
                JobLovModelList = jobLovModelList,
                HotWordList = _homePageService.GetHotWord(20),
            };
            return View(jobBrowseModel);
        }

        #endregion

        #region PrepareJobModel
        /// <summary>
        /// PrepareJobModel
        /// </summary>
        /// <param name="job"></param>
        /// <param name="appliedJobIdList"></param>
        /// <returns></returns>
        [NonAction]
        private JobPositionModel PrepareJobModel(JobPosition job, List<Guid> appliedJobIdList)
        {
            var company = _companyService.GetCompanyById(job.CompanyId.Value);
            //如果公司未找到，则跳转404
            if (company == null)
            {
                throw new NoDataFoundException();
            }
            var jobModel = job.ToModel();
            jobModel.YearsOfExperienceName = _lovService.GetLovName(job.YearsOfExperience.Value);
            jobModel.EducationLevelName = _lovService.GetLovName(job.EducationLevel.Value);
            jobModel.JobTypeName = _lovService.GetLovName(job.JobType);
            jobModel.SalaryRangeName = _lovService.GetLovName(job.SalaryRange.Value);
            var companyModel = company.ToModel();
            jobModel.CompanyModel = companyModel;
            jobModel.CityName = _lovService.GetLovName(job.City);
            jobModel.Welfare = job.Welfare;
            //jobModel.DistrictName = job.District.HasValue ? _lovService.GetLovName(job.District.Value) : String.Empty;
            if (appliedJobIdList != null)
            {
                jobModel.IsApplied = appliedJobIdList.Any(x => x.Equals(job.Id));
            }
            return jobModel;
        }
        #endregion

        #region AdvSearch
        public ActionResult AdvSearch()
        {
            var advSearchViewModel = new AdvSearchViewModel()
            {
                AdvSearchConditionModel = new AdvSearchConditionModel()
            };
            //IndustryList
            advSearchViewModel.IndustryList = GetLovSelectSource(LovType.Industry);
            //JobCategoryGroupList
            advSearchViewModel.JobCategoryList = _lovService.GetLovList(LovType.JobCategory).ToList();
            //JobCategoryList
            advSearchViewModel.SubJobCategoryList = _lovService.GetSubJobCategoryList().ToList();
            //CompanyTypeList
            var companyTypeList = GetLovSelectSource(LovType.CompanyType);
            companyTypeList.RemoveAt(1);
            advSearchViewModel.CompanyTypeList = companyTypeList;
            //PostedDateList
            var postedDateList = GetLovSelectSource(LovType.PostedDate);
            postedDateList.RemoveAt(1);
            advSearchViewModel.PostedDateList = postedDateList;
            //EducationLevelList
            var educationLevelList = GetLovSelectSource(LovType.EducationLevel, false);
            educationLevelList.RemoveAt(0);
            advSearchViewModel.EducationLevelList = educationLevelList;
            //JobTypeList
            var jobTypeList = GetLovSelectSource(LovType.JobType, false);
            jobTypeList.RemoveAt(0);
            advSearchViewModel.JobTypeList = GetLovSelectSource(LovType.JobType, false);
            advSearchViewModel.HotWordList = _homePageService.GetHotWord(20);
            return View(advSearchViewModel);
        }

        [HttpPost]
        public ActionResult AdvSearch(AdvSearchViewModel model)
        {
            Session["AdvSearchConditionModel"] = model.AdvSearchConditionModel;
            return RedirectToAction("SearchJobList", new { isAdvSearch = true });
        }

        private IList<SelectListItem> GetLovSelectSource(LovType lovType, bool addEmptyItem = true)
        {
            var dateList = _lovService.GetLovList(lovType).Select(x => new { x.Name, x.Value }).ToList().
                Select(x => new SelectListItem() { Text = x.Name, Value = x.Value.Value.ToString() }).ToList();
            if (addEmptyItem)
            {
                dateList.Insert(0, new SelectListItem() { Value = "不限", Text = "" });
            }
            return dateList;
        }
        #endregion

        #region RecommendJobs
        public ActionResult RecommendJobs()
        {
            List<JobPosition> jobList = new List<JobPosition>();
            if (Request.IsAuthenticated)
            {
                jobList = _jobPositionService.GetJobsRelatedByJobSeeker(_workContext.CurrentUser.Id).Take(10).ToList();
            }
            else
            {
                var viewdJobs = Request.Cookies["ViewdJobs"];
                if (viewdJobs != null)
                {
                    Guid temp;
                    var viewdJobList = viewdJobs.Value.Split(',').Where(x => !String.IsNullOrWhiteSpace(x) && Guid.TryParse(x, out temp)).
                        Select(x => Guid.Parse(x));
                    jobList = _jobPositionService.GetJobsRelatedByViewdHistory(viewdJobList).Take(10).ToList();
                }
            }
            var model = jobList.Select(x => PrepareJobModel(x, null));
            return PartialView(model);
        }
        #endregion

        #endregion
    }

    public class NoDataFoundException : Exception { }
}
